/**
 * @author fan.donqqing 
 */
package o2o.hx.cron.core.job;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.util.Assert;

/**
 * 任务调度简单封装
 * 
 */
public class ScheduleJob {
	/**
	 * 任务工厂类，产生的任务模式单例模式
	 */
	private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();

	/**
	 * 创建CRON任务
	 * 
	 * @param taskName
	 *            任务名称
	 * @param group
	 *            任务分组，不指定，请输入taskName
	 * @param cron
	 *            时间表达式 crontable 格式
	 * @param task
	 *            任务内容
	 * @return void
	 */
	public static void createCronJob(String taskName, String group, String cron, Object task)
			throws SchedulerException {
		Assert.notNull(taskName, "createCronJob must have taskName");
		Assert.notNull(cron, "createCronJob must have cron express");
		JobDataMap map = new JobDataMap();
		map.put("task", task);
		JobDetail job = newJob(ThirdJob.class).withIdentity(taskName, group).setJobData(map).build();
		Trigger trigger = newTrigger().withIdentity("trigger_" + taskName, group).startNow()
				.withSchedule(cronSchedule(cron).withMisfireHandlingInstructionDoNothing()).build();
		schedulerFactory.getScheduler().scheduleJob(job, trigger);
	}

	/**
	 * 开始调度
	 */
	public static void start() throws SchedulerException {
		schedulerFactory.getScheduler().start();
	}

	/**
	 * 停止调度
	 */
	public static void shutdown() throws SchedulerException {
		schedulerFactory.getScheduler().shutdown();
	}

	/**
	 * 删除任务
	 * 
	 * @param taskName
	 *            任务名称
	 * @param group
	 *            分组
	 * @return void
	 */
	public static void deleteJob(String taskName, String group) throws SchedulerException {
		Assert.notNull(taskName, "deleteJob must have taskName");
		Assert.notNull(group, "stopJob must have group");
		JobKey key = new JobKey(taskName, group);
		schedulerFactory.getScheduler().deleteJob(key);
	}

	/**
	 * 创建简单任务
	 * 
	 * @param taskName
	 *            任务名称
	 * @param group
	 *            任务分组，不指定，请输入taskName
	 * @param hours
	 *            时间单位为小时
	 * @param counts
	 *            执行次数
	 * @param task
	 *            任务内容
	 * @return void
	 */
	public static void createSimpleJobByHourWithGiveCounts(String taskName, String group, Integer hours, Integer counts,
			Object task) throws SchedulerException {
		Assert.notNull(taskName, "createSimpleJobWithGiveCounts must have taskName");
		Assert.notNull(group, "createSimpleJobWithGiveCounts must have group");
		JobDataMap map = new JobDataMap();
		map.put("task", task);
		JobDetail job = newJob(ThirdJob.class).withIdentity(taskName, group).setJobData(map).build();
		simpleSchedule().withIntervalInHours(hours);
		Trigger trigger = newTrigger().withIdentity("trigger_" + taskName, group).startNow()
				.withSchedule(SimpleScheduleBuilder.repeatHourlyForTotalCount(counts)).build();
		schedulerFactory.getScheduler().scheduleJob(job, trigger);
	}

	/**
	 * 创建简单任务
	 * 
	 * @param taskName
	 *            任务名称
	 * @param group
	 *            任务分组，不指定，请输入taskName
	 * @param minute
	 *            时间单位为分钟
	 * @param counts
	 *            执行次数
	 * @param task
	 *            任务内容
	 * @return void
	 */
	public static void createSimpleJobByMinuteWithGiveCounts(String taskName, String group, Integer minute,
			Integer counts, Object task) throws SchedulerException {
		Assert.notNull(taskName, "createSimpleJobWithGiveCounts must have taskName");
		Assert.notNull(group, "createSimpleJobWithGiveCounts must have group");
		JobDataMap map = new JobDataMap();
		map.put("task", task);
		JobDetail job = newJob(ThirdJob.class).withIdentity(taskName, group).setJobData(map).build();
		simpleSchedule().withIntervalInMinutes(minute);
		Trigger trigger = newTrigger().withIdentity("trigger_" + taskName, group).startNow()
				.withSchedule(SimpleScheduleBuilder.repeatMinutelyForever(counts)).build();
		schedulerFactory.getScheduler().scheduleJob(job, trigger);
	}

	/**
	 * 创建简单任务
	 * 
	 * @param taskName
	 *            任务名称
	 * @param group
	 *            任务分组，不指定，请输入taskName
	 * @param seconds
	 *            时间单位为秒
	 * @param counts
	 *            执行次数
	 * @param task
	 *            任务内容
	 * @return void
	 */
	public static void createSimpleJobBySecondsWithGiveCounts(String taskName, String group, Integer seconds,
			Integer counts, Object task) throws SchedulerException {
		Assert.notNull(taskName, "createSimpleJobWithGiveCounts must have taskName");
		Assert.notNull(group, "createSimpleJobWithGiveCounts must have group");
		JobDataMap map = new JobDataMap();
		map.put("task", task);
		JobDetail job = newJob(ThirdJob.class).withIdentity(taskName, group).setJobData(map).build();
		Trigger trigger = newTrigger().withIdentity("trigger_" + taskName, group).startNow()
				.withSchedule(simpleSchedule().withIntervalInSeconds(seconds)).build();
		schedulerFactory.getScheduler().scheduleJob(job, trigger);
	}

	/**
	 * 停止任务
	 * 
	 * @param taskName
	 *            任务名称
	 * @param group
	 *            分组
	 * @return void
	 */
	public static void stopJob(String taskName, String group) throws SchedulerException {
		Assert.notNull(taskName, "stopJob must have taskName");
		Assert.notNull(group, "stopJob must have group");
		JobKey key = new JobKey(taskName, group);
		schedulerFactory.getScheduler().pauseJob(key);
	}

	/**
	 * 恢复任务，与停止任务对应
	 * 
	 * @param taskName
	 *            任务名称
	 * @param group
	 *            分组
	 * @return void
	 */
	public static void resumeJob(String taskName, String group) throws SchedulerException {
		Assert.notNull(taskName, "resumeJob must have taskName");
		Assert.notNull(group, "resumeJob must have group");
		JobKey key = new JobKey(taskName, group);
		schedulerFactory.getScheduler().resumeJob(key);
	}

	/**
	 * 立即执行任务
	 * 
	 * @param taskName
	 *            任务名称
	 * @param group
	 *            分组
	 * @return void
	 */
	public static void runJobAtOnce(String taskName, String group) throws SchedulerException {
		Assert.notNull(taskName, "runJobAtOnce must have taskName");
		Assert.notNull(group, "runJobAtOnce must have group");
		JobKey key = new JobKey(taskName, group);
		schedulerFactory.getScheduler().triggerJob(key);
	}
}
